tree grammar LocStatCheckPass;

options {
	tokenVocab = LocStat;
	ASTLabelType = LocStatAST;
	filter = true;
}

@header {
	package data.analysis.grammar;
	
	import data.analysis.grammar.symbol.*;
}

@members {
	SymbolTable symbolTable;
	Scope currentScope;
	
	public LocStatCheckPass(TreeNodeStream in, SymbolTable symbolTable) {
		this(in);
		this.symbolTable = symbolTable;
		currentScope = symbolTable.getGlobalScope();
	}
}

topdown
	:	subj
	|	condDown
	|	script
	|	scopedSubjDown
	;
	
bottomup
	:	count
	|	fraction
	|	mean
	|	med
	|	scopedSubjUp
	|	condUp
	;
	
subj:	^(SUBJECT ID .*)
		{
		$ID.scope = currentScope;
		symbolTable.resolve($ID);
		}
	;
	
script
	:	SCRIPT
		{
		LocStatAST str = (LocStatAST)$SCRIPT.getParent().getChild(1);
		str.scope = currentScope;
		symbolTable.resolveScript(str);
		}
	;
	
condDown
	:	^(COND . .) 
		{
		$COND.lastScope = $COND.scope = currentScope;
		currentScope = symbolTable.findCondScope($COND);
		}
	;
	
scopedSubjDown
	:	SCOPE_OP 
		{
		$SCOPE_OP.lastScope = $SCOPE_OP.scope = currentScope;
		currentScope = symbolTable.findScopeOpScope($SCOPE_OP);
		}
	;
	
count
	:	^(COUNT a=.) {symbolTable.handleCount($a);}
	;
	
fraction
	:	^(FRACTION a=. b=.) {symbolTable.handleFrac($a, $b);}
	;
	
mean:	^(MEAN a=. b=.) {symbolTable.handleMean($a, $b);}
	;
	
med	:	^(MEDIAN a=. b=.) {symbolTable.handleMed($a, $b);}
	;
	
scopedSubjUp
	:	SCOPE_OP 
		{
		currentScope = $SCOPE_OP.lastScope;
		$SCOPE_OP.evalType = ((LocStatAST)$SCOPE_OP.getChild(0)).evalType;
		}
	;
	
condUp
	:	^(COND a=. b=.) 
		{
		symbolTable.handleCond($COND);
		currentScope = $COND.lastScope;
		}
	;